package com.gdc.microservicecloud.config;

import com.gdc.myrule.MySelfRule_Advanced;
import com.netflix.loadbalancer.IRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * Description: 配置 Bean
 * @author: gdc
 * @date: 2021/1/17
 * @version 1.0
 */
@Configuration
public class ConfigBean {

    /**
     * 注入 restTemplate Bean
     *
     * | @LoadBalanced      使 RestTemplate 具有了客户端负载均衡能力
     *      作用： 使用了这个注解以后 ，会在  restTemplate 里面 通过 restTemplate.setInterceptors 放入  LoadBalancerInterceptor ，
     *          这个过滤器会在 请求远程成接口的时候 动态判断请求的域是不是  负载 负载均衡支付的服务的地址，如果是，那么就会代理 使用 这个负载均衡器 来调用。
     *
     * @return              RestTemplate
     */
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }


    /**
     * 修改 Balance 负载规则
     * Ribbon中的7中负载均衡算法：
     *
     * （1）RoundRobinRule：轮询；
     * （2）RandomRule：随机；
     * （3）AvailabilityFilteringRule：会先过滤掉由于多次访问故障而处于断路器状态的服务，还有并发的连接数量超过阈值的服务，然后对剩余的服务列表按照轮询策略进行访问；
     * （4）WeightedResponseTimeRule：根据平均响应时间计算所有服务的权重，响应时间越快的服务权重越大被选中的概率越大。刚启动时如果统计信息不足，则使用RoundRobinRule（轮询）策略，等统计信息足够，会切换到WeightedResponseTimeRule；
     * （5）RetryRule：先按照RoundRobinRule（轮询）策略获取服务，如果获取服务失败则在指定时间内进行重试，获取可用的服务；
     * （6）BestAvailableRule：会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务，然后选择一个并发量最小的服务；
     * （7）ZoneAvoidanceRule：复合判断Server所在区域的性能和Server的可用性选择服务器；
     *
     */
    @Bean
    public IRule myRule(){
        //return new RoundRobinRule();
        //return new RandomRule();
        //return new AvailabilityFilteringRule();
        //return new WeightedResponseTimeRule();
        //return new RetryRule();
        //return new BestAvailableRule();
        //return new ZoneAvoidanceRule();

        // 启用自定义规则
        return new MySelfRule_Advanced();
    }
}
